home *** CD-ROM | disk | FTP | other *** search
- /* SourceServer.c: How to create and send an AppleEvent to SourceServer for ProjectDrag.
- *
- * A set of applets for drag and drop source control by Tim Maroney.
- * See develop, issue 23 for details.
- *
- * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
- * and using the MoreFiles utilities by Jim Luther.
- *
- * This software is free, but don't modify and redistribute it without
- * changing the status window to indicate your name and your changes!
- */
-
- #include <Errors.h>
- #include <Finder.h>
- #include <Strings.h>
- #include <string.h>
-
- #include "SourceServer.h"
- #include "MoreFiles.h"
- #include "MoreFilesExtras.h"
- #include "DSUtils.h"
- #include "SignatureToApp.h"
- #include "ProjectAlias.h"
- #include "PDDialogs.h"
- #include "PDUtilities.h"
- #include "TasksAndErrors.h"
-
-
- #define kSSCommandID 'cmnd'
-
-
-
- /* send an Apple event to SourceServer. See develop 23 for details */
-
- OSErr SourceServerCommand(AEDesc *command, CStringHandle *output, CStringHandle *diagnostic,
- AEIdleUPP idleProc, AEFilterUPP filterProc)
- {
- AppleEvent aeEvent, aeReply;
- AEDesc sourceServerAddress;
- ProcessSerialNumber sourceServerProcess;
- FSSpec appSpec; /* SignatureToApp requires this, documentation to the contrary.... */
- long theLong, theSize;
- DescType theType;
- AEDesc paramDesc;
- OSErr err;
-
- /* default replies */
- *output = NULL;
- *diagnostic = NULL;
-
- /* find the SourceServer */
- TaskStart(kProjectDragStrings, kFindingSourceServer, NULL, NULL, NULL, NULL);
- err = SignatureToApp(kSourceServerCreator, NULL, &sourceServerProcess, &appSpec, NULL,
- Sig2App_LaunchApplication, launchContinue + launchDontSwitch);
- if (err != noErr) return err;
- err = AECreateDesc(typeProcessSerialNumber, (Ptr) &sourceServerProcess, sizeof(ProcessSerialNumber),
- &sourceServerAddress);
- if (err != noErr) return err;
- TaskDone();
-
- /* Create the SourceServer Apple Event */
- err = AECreateAppleEvent(kSourceServerType, kSSCommandID, &sourceServerAddress, kAutoGenerateReturnID,kAnyTransactionID,
- &aeEvent);
- AEDisposeDesc(&sourceServerAddress);
- if (err != noErr) return err;
-
- /* add the command descriptor to the event */
- err = AEPutParamDesc(&aeEvent, keyDirectObject, command);
- if (err != noErr) { AEDisposeDesc(&aeEvent); return err; }
-
- /* send the apple event */
- err = AESend(&aeEvent, &aeReply, kAEWaitReply + kAENeverInteract, kAENormalPriority,
- kNoTimeOut, idleProc, filterProc);
- AEDisposeDesc(&aeEvent);
- if (err != noErr) return err;
-
- /* check for an error return */
- err = AEGetParamPtr(&aeReply, keyErrorNumber, typeInteger, &theType, &theLong,
- sizeof(long), &theSize);
- if (err != noErr || (err = theLong) != noErr)
- return err;
-
- /* get the command output */
- err = AEGetParamDesc (&aeReply, keyDirectObject, typeChar, ¶mDesc);
- if (err == noErr)
- *output = (CStringHandle)paramDesc.dataHandle;
-
- /* get the diagnostic output */
- err = AEGetParamDesc (&aeReply, 'diag', typeChar, ¶mDesc);
- if (err == noErr)
- *diagnostic = (CStringHandle)paramDesc.dataHandle;
-
- /* get the MPW status -- it becomes our error return */
- err = AEGetParamPtr(&aeReply, 'stat', typeInteger, &theType, &theLong,
- sizeof(long), &theSize);
- if (err == noErr)
- err = theLong;
-
- AEDisposeDesc(&aeReply);
-
- return err;
- }
-
-
- OSErr CreateCommand(AEDesc *command, CString commandText)
- {
- OSErr err = AECreateList(NULL, 0 , false, command);
- if (err == noErr)
- {
- err = AddCStringArg(command, commandText);
- if (err != noErr) AEDisposeDesc(command);
- }
- if (err != noErr)
- {
- /* this makes it safe to dispose the descriptor */
- command->descriptorType = typeNull;
- command->dataHandle = NULL;
- }
- return err;
- }
-
-
- OSErr AddCommentArg(AEDesc *command, StringPtr comment)
- {
- OSErr err;
- if (comment[0] == 0) return noErr;
- err = AddCStringArg(command, "-cs");
- if (err != noErr) return err;
- err = AddPStringArg(command, comment);
- return err;
- }
-
-
- OSErr AddDirArg(AEDesc *command, short vRefNum, long folderID)
- {
- FSSpec dirSpec;
- OSErr err = AddCStringArg(command, "-d");
- if (err != noErr) return err;
- dirSpec.vRefNum = vRefNum;
- dirSpec.parID = folderID;
- dirSpec.name[0] = 0;
- err = AddFileNameArg(command, &dirSpec);
- return err;
- }
-
-
- OSErr AddProjectArg(AEDesc *command, StringPtr projectName)
- {
- OSErr err = AddCStringArg(command, "-project");
- if (err != noErr) return err;
- err = AddPStringArg(command, projectName);
- return err;
- }
-
-
- OSErr AddUserArg(AEDesc *command, StringPtr userName)
- {
- OSErr err = AddCStringArg(command, "-u");
- if (err != noErr) return err;
- err = AddPStringArg(command, userName);
- return err;
- }
-
-
- OSErr AddFileNameArg(AEDesc *command, FSSpec *file)
- {
- Str255 fileName;
- OSErr err = MakeFullPathName(file, fileName);
- if (err != noErr) return err;
- err = AddPStringArg(command, fileName);
- return err;
- }
-
-
- OSErr AddPStringArg(AEDesc *command, StringPtr string)
- {
- OSErr err;
- p2cstr(string);
- err = AEPutPtr(command, 0, typeChar, string, strlen(string) + 1);
- c2pstr(string);
- return err;
- }
-
-
- OSErr AddCStringArg(AEDesc *command, CString string)
- {
- OSErr err = AEPutPtr(command, 0, typeChar, string, strlen(string) + 1);
- return err;
- }
-
-
- /* utility routines with task and error notification built in */
-
-
- OSErr SendCommand(AEDesc *command)
- {
- OSErr err;
- CStringHandle output = NULL, diagnostic = NULL;
-
- err = SourceServerCommand(command, &output, &diagnostic, ProjectDragIdleProc, NULL);
- if (err != noErr || diagnostic != NULL)
- {
- if (err == noErr) err = -1;
- if (diagnostic != NULL)
- ResTextDisplayDialog(kProjectDragStrings, kProjectorError, diagnostic);
- else
- RaiseErrorNumber(err);
- }
- else if (output != NULL)
- ResTextDisplayDialog(kProjectDragStrings, kProjectorOutput, output);
- if (output != NULL)
- DisposeHandle((Handle)output);
- if (diagnostic != NULL)
- DisposeHandle((Handle)diagnostic);
- AEDisposeDesc(command);
- return err;
- }
-
-
- OSErr MountProject(AliasHandle projectAlias)
- {
- OSErr err;
- CStringHandle output = NULL, diagnostic = NULL;
-
- err = MountProjectAlias(projectAlias, &output, &diagnostic);
- if (err != noErr || diagnostic != NULL)
- {
- if (err == noErr) err = -1;
- if (diagnostic != NULL)
- ResTextDisplayDialog(kProjectDragStrings, kCantFindProject, diagnostic);
- else
- RaiseErrorNumber(err);
- }
- if (output != NULL)
- DisposeHandle((Handle)output);
- if (diagnostic != NULL)
- DisposeHandle((Handle)diagnostic);
- DisposeHandle((Handle)projectAlias);
- return err;
- }
-
-
- OSErr MountProjectFromFolder(short vRefNum, long folderID, StringPtr projectName)
- {
- AliasHandle projectAlias;
- OSErr err;
-
- TaskStart(kProjectDragStrings, kFindingProject, NULL, NULL, NULL, NULL);
- err = FindProjectAliasFromFolder(vRefNum, folderID, &projectAlias, projectName);
- if (err != noErr)
- {
- /* couldn't find it -- ask the user for one */
- FSSpec file;
- if (SelectProjectorDB(&file, kProjectDragStrings, kCantFindProjectCanYou, NULL, NULL))
- {
- Str31 folderName;
-
- /* get the name of the parent of ProjectorDB -- it's the project name */
- err = GetDirName(file.vRefNum, file.parID, projectName);
- if (err != noErr) return RaiseErrorNumber(err);
-
- /* get the name of the parent of the checkout folder */
- err = GetDirName(vRefNum, folderID, folderName);
- if (err != noErr) return RaiseErrorNumber(err);
-
- /* if the name of the checkout folder is different from the project name,
- * we need to create a mapping between them
- */
- if (!EqualString(folderName, projectName, false, false))
- {
- err = AddNameMapping(folderName, projectName);
- if (err != noErr) return RaiseErrorNumber(err);
- }
-
- /* user picked a ProjectorDB -- now make an alias for it */
- err = MakeProjectAlias(file.vRefNum, file.parID, &projectAlias);
- if (err != noErr) return RaiseErrorNumber(err);
- }
- else
- {
- /* user canceled the standard file dialog */
- return RaiseErrorNumber(userCanceledErr);
- }
- }
- TaskDone();
- return MountProject(projectAlias);
- }
-
-
- /* filter ProjectorDB files based on project name -- must be the same as in the CKID */
-
- pascal Boolean FindProjectFileFilter(CInfoPBPtr pb, Ptr myDataPtr)
- {
- StringPtr projectName = myDataPtr;
- Str63 folderName;
- OSErr err;
-
- /* get the name of the parent folder */
- err = GetDirName(pb->hFileInfo.ioVRefNum, pb->hFileInfo.ioFlParID, folderName);
- if (err != noErr) return true; /* error means suppress */
-
- /* compare them */
- return !EqualString(projectName, folderName, false, false);
- }
-
-
- OSErr MountProjectFromCKID(CKIDHandle theCKID, StringPtr projectName)
- {
- AliasHandle projectAlias;
- OSErr err;
-
- TaskStart(kProjectDragStrings, kFindingProject, NULL, NULL, NULL, NULL);
- err = FindProjectAliasFromCKID(theCKID, &projectAlias, projectName);
- if (err != noErr)
- {
- FSSpec file;
- Str31 topProjectName;
-
- GetTopProjectName(projectName, topProjectName);
- if (SelectProjectorDB(&file, kProjectDragStrings, kCantFindProjectCanYou,
- FindProjectFileFilter, topProjectName))
- {
- err = MakeProjectAlias(file.vRefNum, file.parID, &projectAlias);
- if (err != noErr) return RaiseErrorNumber(err);
- }
- else
- {
- return RaiseErrorNumber(userCanceledErr);
- }
- }
- TaskDone();
- return MountProject(projectAlias);
- }
-